#pragma once
#include<iostream>
#include<queue>
#include<pthread.h>
#include<stdio.h>

template<class T>
class blockqueue
{
public:
    blockqueue(int capacity)
        :_Capacity(capacity)
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_Ccond,nullptr);
        pthread_cond_init(&_Pcond,nullptr);
    }
    ~blockqueue()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_Ccond);
        pthread_cond_destroy(&_Pcond);
    }
    //生产
    void Push(T&task )
    {
        pthread_mutex_lock(&_mutex);
        while(_bq.size()==_Capacity)  //条件不满足都进入等待，通过消费者来进行唤醒线程
            pthread_cond_wait(&_Pcond,&_mutex); //_Pcond生产者的条件变量   
        _bq.push(task);
        pthread_cond_signal(&_Ccond);  //给消费者条件变量发信号，使其唤醒等待中的消费者线程
        pthread_mutex_unlock(&_mutex);
    }
    //消费
    T Pop()
    {
        pthread_mutex_lock(&_mutex);
        while(_bq.size()==0)
            pthread_cond_wait(&_Ccond,&_mutex);
        T out=_bq.front();
        _bq.pop();
        pthread_cond_signal(&_Pcond);
        pthread_mutex_unlock(&_mutex);
        return out; 
    }
private:
    std::queue<T> _bq;
    int _Capacity;
    pthread_mutex_t _mutex;
    pthread_cond_t _Ccond; //消费者
    pthread_cond_t _Pcond; //生产者

};